from jenkins import Jenkins
from time import sleep
from jsonpath import jsonpath
from Common.ReadYaml import ConfigYaml


def deleteRepeat(in_list, key):
    '''

    :param in_list:
    :param key:
    :return:
    '''

    out_list = []
    out_list.append(in_list[0])
    for dict in in_list:
        index = 0
        for item in out_list:
            if dict[key] != item[key]:
                index += 1
            else:
                break
            if index == len(out_list):
                out_list.append(dict)

    return out_list


class JenkinsJob(object):
    all_task_data = []

    def __init__(self):
        self.jenkins_url = ConfigYaml('jenkins_url').base_config
        self.juser_name = ConfigYaml('juser_name').base_config
        self.jpassword = ConfigYaml('jpassword').base_config
        self.ajenkins_url = ConfigYaml('ajenkins_url').base_config
        self.ajuser_name = ConfigYaml('ajuser_name').base_config
        self.apassword = ConfigYaml('apassword').base_config

    def jenkins_conn(self, switch=True):
        '''
        简历jenkins链接
        :return:
        '''
        if switch:
            return Jenkins(self.jenkins_url, username=self.juser_name, password=self.jpassword)
        else:
            return Jenkins(self.ajenkins_url, username=self.ajuser_name, password=self.apassword)

    def build(self, conn, job_name, data):
        '''
        构件定时任务
        :param con:
        :param kwargs:
        :return:
        '''
        conn.build_job(job_name, parameters=data)

    def get_jobs(self, conn):
        '''
        获取构建任务列表
        :return:
        '''
        return conn.get_all_jobs()

    def last_build_number(self,conn, job_name):
        '''
        获取最新的节点
        :param note:
        :return:
        '''
        return conn.get_job_info(job_name).get("lastCompletedBuild").get("number")

    def assert_job_exists(self, conn, job_name):
        '''
        判断构件任务是否存在
        :param note:
        :return:
        '''
        is_exists = True
        try:
            conn.assert_job_exists(job_name)
        except:
            is_exists = False

        finally:
            return is_exists

    def build_info(self, conn, job_name, number):
        '''
        :return:
        '''
        return conn.get_build_info(job_name, number).get("result")

    def get_building_info(self, conn):
        '''
        :return:
        '''
        return conn.get_running_builds()

    def queue_info(self, conn):
        '''
        :return:
        '''
        return conn.get_queue_info()

    def get_jobs_status(self, conn, job_name):
        '''

        :param job_name:
        :return:
        '''
        is_exists = self.assert_job_exists(conn, job_name)
        param = ""
        if is_exists:
            queue_status = conn.get_job_info(job_name).get("inQueue")
            if queue_status:  # 排队中
                job_statue = 'pending'
                running_number = conn.get_job_info(job_name).get("nextBuildNumber")
            else:
                running_number = conn.get_job_info(job_name).get("nextBuildNumber") - 1    #获取当前正在构建的任务number
                try:
                    build_info = conn.get_build_info(job_name, running_number)
                    running_status = build_info.get('building')                             # 判断job是否在执行中
                    param = jsonpath(build_info, "$..parameters[*].value")
                    if running_status:
                        job_statue = 'running'
                    else:
                        job_statue = self.build_info(conn, job_name, running_number)

                except:
                    last_build_number = self.last_build_number(conn, job_name)   #构件编号
                    job_statue = self.build_info(conn, job_name, last_build_number)   #构建状态

            return job_statue, running_number, param

    def get_all_build_param(self, conn, running_task, queue_task):
        '''
        获取所有构建服务参数--仅包含构建中和pending中的
        :return:
        '''
        param_list = []
        if running_task:
            task_list = deleteRepeat(running_task, "number")
            for value in task_list:
                server_name = value.get("url").split("/")[-3]
                job_name = f"erp-project/{server_name}"
                last_number = self.last_build_number(conn, job_name)
                if value.get("number") >= last_number:
                    job_statue, running_number, param = self.get_jobs_status(conn, job_name)
                    if param:
                        param_list.append(param[1])

        if queue_task:
            for queue in queue_task:
                param_list.append(queue.get("parameters")[0].get("value"))

        return param_list

    def get_auto_build_param(self, conn, running_task, queue_task):
        '''
        获取所有构建服务参数--仅包含构建中和pending中的
        :return:
        '''
        param_list = []
        if running_task:
            task_list = deleteRepeat(running_task, "number")
            for value in task_list:
                server_name = value.get("url").split("/")[-3]
                job_name = server_name
                last_number = self.last_build_number(conn, job_name)
                if value.get("number") >= last_number:
                    job_statue, running_number, param = self.get_jobs_status(conn, job_name)
                    if param:
                        param_list.append(param[0])

        if queue_task:
            for queue in queue_task:
                param_list.append(queue.get("actions")[0].get("parameters")[0].get("value"))

        return param_list

    def build_process(self, job_list, job):
        '''

        :param conn:
        :param job_list:
        :return:
        '''
        json_data = {"env": "qa"}
        conn = self.jenkins_conn()
        auto_conn = self.jenkins_conn(switch=False)
        font_running_task = self.get_building_info(conn)
        font_queue_task = self.queue_info(conn)
        font_task_job = self.get_all_build_param(conn, font_running_task, font_queue_task)
        JenkinsJob.all_task_data.extend(font_task_job)
        for job_name in job_list:
            print("当前探测服务：", job_name)
            num = 0
            while True:
                num += 1
                job_statue, running_number, param = jenkins.get_jobs_status(conn, job_name)
                print("任务执行状态：", job_statue)
                print("任务执行编号：", running_number)
                if job_statue in ("pending", "running"):
                    sleep(10)
                    if num > 66:
                        break
                else:
                    break

        after_running_task = self.get_building_info(conn)
        after_queue_task = self.queue_info(conn)
        after_task_job = self.get_all_build_param(conn, after_running_task, after_queue_task)

        if after_task_job:
            JenkinsJob.all_task_data.extend(after_task_job)
            return self.build_process(job_list, job)
        if JenkinsJob.all_task_data:
            auto_task = self.get_building_info(auto_conn)
            queue_task = self.queue_info(auto_conn)
            all_param = self.get_auto_build_param(auto_conn, auto_task, queue_task)
            for task in font_task_job:
                if task not in all_param:
                    json_data["env"] = task
                    print("执行自动化脚本构建中...")
                    self.build(auto_conn, job, json_data)


if __name__ == '__main__':
    job_list = ["erp-project/basic-data-service", "erp-project/bi-service",
                "erp-project/channel-order-backend", "erp-project/channel-product-backend",
                "erp-project/channel-service", "erp-project/eureka",
                "erp-project/finance-service", "erp-project/gateway",
                "erp-project/goods-operation-calculation", "erp-project/goods-operation-datasync",
                "erp-project/goods-operation-export",
                "erp-project/goods-operation-service", "erp-project/order-backstage-service",
                "erp-project/order-web-service", "erp-project/plm-design-service",
                "erp-project/plm-product-backend", "erp-project/plm-product-service",
                "erp-project/product-backend", "erp-project/product-service",
                "erp-project/purchase-backend", "erp-project/purchase-export",
                "erp-project/purchase-service",
                "erp-project/quality-assurance-backend",
                "erp-project/quality-assurance-poi", "erp-project/quality-assurance-service",
                "erp-project/reverse-order-backend", "erp-project/reverse-order-web",
                "erp-project/shipping-backend", "erp-project/shipping-export",
                "erp-project/shipping-service", "erp-project/supplier-data-service",
                "erp-project/tracking-service", "erp-project/tracking-web",
                "erp-project/translation",
                "erp-project/user-service", "erp-project/warehouse-service",
                "erp-project/web-front-new"
                ]

    jenkins = JenkinsJob()
    while True:
        jenkins.build_process(job_list, "auto_erp")
        sleep(120)


